<!--
/*
 * Copyright 2017 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<!DOCTYPE html>
<html lang="en">
  <head>
  <script>
    // Catch any possible error and show an alert. 
    // Useful for "hacky" debugging.
     window.addEventListener('error', function(event) {
      var errorMessage = event.message;
      var url = event.filename;
      var lineNumber = event.lineno;
      var columnNumber = event.colno;
      alert("ERROR: " + errorMessage + " at " + url + " : " + lineNumber + 
        " : " + columnNumber);
    });
  </script>
  <title>WebAR (Tango) Picking ThreeJS Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, user-scalable=no,
    minimum-scale=1.0, maximum-scale=1.0">
  <style>
    body {
      font-family: Monospace;
      background-color: #000000;
      margin: 0px;
      overflow: hidden;
    }

    #info {
      color: #fff;
      position: absolute;
      bottom: 10px;
      width: 100%;
      text-align: center;
      z-index: 100;
      display:block;

    }

    a { color: skyblue }
  </style>
  </head>
  <body>
    <div id="info">
      <a href="http://threejs.org" target="_blank">three.js</a>
      WebAR (Tango) Picking ThreeJS Example
      <a href="https://github.com/judax" target="_blank">Iker Jamardo</a>
    </div>

    <script src="libs/third_party/three.js"></script>
    <script src="libs/third_party/Detector.js"></script>
    <script src="libs/third_party/stats.min.js"></script>
    <script src="libs/third_party/VRControls.js"></script>
    <script src="libs/third_party/dat.gui.min.js"></script>

    <script src="libs/THREE.WebAR.js"></script>

    <script>
      function GUI() {
        this.showSeeThroughCamera = true;
        this.continuousPicking = false;
        this.showPointCloud = true;
        this.pointsToSkip = 0;
        return this;
      }

      if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

      var container, stats;
      var cameraOrtho, cameraPersp, cameraScene, scene, renderer, cameraMesh;
      var pointCloud, points;
      var vrDisplay;
      var model;
      var gui;
      var pos = new THREE.Vector3(); // Avoid GC.

      var MODEL_SIZE_IN_METERS = 0.1;

      // WebAR is currently based on the WebVR API so try to find the right
      // VRDisplay instance.
      if (navigator.getVRDisplays) {
        navigator.getVRDisplays().then(function(vrDisplays) {
          if (vrDisplays && vrDisplays.length > 0) {
            for (var i = 0; !vrDisplay && i < vrDisplays.length; i++) {
              vrDisplay = vrDisplays[i];
              if (vrDisplay.displayName !== "Tango VR Device") {
                vrDisplay = null;
              }
            }
          }
          if (!vrDisplay) {
            alert("No Tango WebAR VRDisplay found. Falling back to a video.");
          }
          init(vrDisplay);
          updateAndRender();  
        });
      }
      else {
        alert("No navigator.getVRDisplays. Falling back to a video.");
        init();
        updateAndRender();
      }

      function init(vrDisplay) {
        // Initialize the dat.GUI.
        var datGUI = new dat.GUI();
        gui = new GUI();
        datGUI.add(gui, "showSeeThroughCamera").name("Show seethrough camera");
        datGUI.add(gui, "continuousPicking").name("Continuous picking");
        datGUI.add(gui, "showPointCloud").onFinishChange(function(value) {
          if (value) {
            scene.add(points)
          }
          else {
            scene.remove(points);
          }
        }).name("Show Point Cloud");
        datGUI.add(gui, "pointsToSkip", 0, 10).name("Points to kip");

        // Initialize everything related to ThreeJS.
        container = document.createElement( 'div' );
        document.body.appendChild( container );

        // Create the see through camera scene and camera
        cameraScene = new THREE.Scene();
        cameraOrtho = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 100 );
        cameraMesh = THREE.WebAR.createVRSeeThroughCameraMesh(vrDisplay, 'videos/sintel.webm');
        cameraScene.add(cameraMesh);

        // Create the 3D scene and camera
        scene = new THREE.Scene();
        // Use the THREE.WebAR utility to create a perspective camera
        // suited to the actual see through camera parameters.
        cameraPersp = 
          THREE.WebAR.createVRSeeThroughCamera(vrDisplay, 0.01, 100);
        // Create a cube model of 10 cm size.
        model = new THREE.Mesh(new THREE.ConeBufferGeometry(
          MODEL_SIZE_IN_METERS / 2, MODEL_SIZE_IN_METERS), 
          new THREE.MeshLambertMaterial( {color: 0x888888 } ));
        // Apply a rotation to the model so it faces in the direction of the
        // normal of the plane when the picking based reorientation is done
        model.geometry.applyMatrix(
          new THREE.Matrix4().makeRotationZ(THREE.Math.degToRad(-90)));
        model.position.set(0, 0, -2);
        scene.add(model);
        var pointsMaterial = new THREE.PointsMaterial( 
          { size: 0.01, vertexColors: THREE.VertexColors } );
        pointsMaterial.depthWrite = false;
        pointCloud = new THREE.WebAR.VRPointCloud(vrDisplay, true);
        points = new THREE.Points(pointCloud.getBufferGeometry(),
          pointsMaterial);
        // Points are changing all the time so calculating the frustum culling
        // volume is not very convenient.
        points.frustumCulled = false;
        points.renderDepth = 0;
        if (gui.showPointCloud)
          scene.add(points);

        // Control the perspective camera using the VR pose.
        vrControls = new THREE.VRControls(cameraPersp);

        // Add some lighting
        var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
        directionalLight.position.set( 0, 1, 0);
        scene.add( directionalLight );

        // Create the renderer
        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        // It is important to specify that the color buffer should not be
        // automatically cleared. The see through camera will render the whole
        // background.
        renderer.autoClear = false;
        document.body.appendChild( renderer.domElement );

        // Create a way to measure performance
        stats = new Stats();
        container.appendChild( stats.dom );

        // Control the resizing of the window to correctly display the scene.
        window.addEventListener( 'resize', onWindowResize, false );

        // Wherever the user clicks in the screen, place the model.
        renderer.domElement.addEventListener("click", function(event) {
          pos.x = event.pageX / window.innerWidth;
          pos.y = event.pageY / window.innerHeight;
          picking();
        });
      }

      function picking() {
        if (vrDisplay) {
          var pointAndPlane = 
            vrDisplay.getPickingPointAndPlaneInPointCloud(pos.x, pos.y);
          if (pointAndPlane) {
            // Orient and position the model in the picking point according
            // to the picking plane. The offset is half of the model size.
            THREE.WebAR.
              positionAndRotateObject3DWithPickingPointAndPlaneInPointCloud(
                pointAndPlane, model, MODEL_SIZE_IN_METERS / 2);
          }
          else {
            console.warn("Could not retrieve the correct point and plane.");
          }
        }
      }

      function onWindowResize() {
        THREE.WebAR.resizeVRSeeThroughCamera(vrDisplay, cameraPersp);
        renderer.setSize( window.innerWidth, window.innerHeight );
      }

      function updateAndRender() {
        // UPDATE

        stats.update();

        // Update the perspective scene
        vrControls.update();

        // Update the point cloud. Only if the point cloud will be shown the
        // geometry is also updated.
        pointCloud.update(gui.showPointCloud, gui.pointsToSkip);

        // If continuous picking is enabled, use the center of the screen
        // to continuously pick.
        if (gui.continuousPicking) {
          pos.x = 0.5;
          pos.y = 0.5;
          picking();
        }

        // Make sure that the camera is correctly displayed depending on the
        // device and camera orientations.
        THREE.WebAR.updateCameraMeshOrientation(vrDisplay, cameraMesh);

        // RENDER

        // Render the see through camera scene
        renderer.clear();

        if (gui.showSeeThroughCamera)
          renderer.render( cameraScene, cameraOrtho );

        // Render the perspective scene
        renderer.clearDepth();

        renderer.render( scene, cameraPersp );

        requestAnimationFrame( updateAndRender );
      }

    </script>
  </body>
</html>
